Skip to content

Conversation

uhoreg
Copy link
Member

@uhoreg uhoreg commented Oct 8, 2025

Fixes #30946

Adds a devtool that allows you to look at users and their devices, and shows information about them, including verification status.

image image image

Checklist

Copy link
Member

@richvdh richvdh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally, looks very nice. A few stylistic things.

*
* By default, filters to only show joined users.
*
* If the `member` state is set, delegates to `User` to view a single user.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is User? Should this be an {@link} ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also: the talk of state seems like an implementation detail which does not belong in the doc-comment?

Suggested change
* If the `member` state is set, delegates to `User` to view a single user.
* Once the user chooses a specific member, delegates to {@link UserView} to view a single user.

/**
* Shows a list of users in the room, and allows selecting a user to view.
*
* By default, filters to only show joined users.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how does one override this default, as a user of the component?

/**
* Shows a single user to view, and allows selecting a device to view.
*
* If the `device` state is set, delegates to `Device` to show a single device.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as above, this needs attention

const UserView: React.FC<UserProps> = ({ member, onBack }) => {
const context = useContext(DevtoolsContext);
const crypto = context.room.client.getCrypto();
const verificationStatus = useAsyncMemo(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it would probably be helpful to add a comment documenting the type and possible values of verificationStatus, since it's not obvious at a glance

hideTooltip={true}
status={E2EStatus.Verified}
className="mx_E2EIcon_inline"
/>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm no react expert, but ... putting this into useAsyncMemo feels a bit cumbersome to me. Wouldn't it be more natural to just to do:

const verificationStatus = useAsyncMemo(async () => {
    return await crypto?.getUserVerificationStatus(member.userId);
}, ... );

... and put the rest outside useAsyncMemo?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's actually how I had it originally, but it all migrated into the useAsyncMemo. I don't remember the exact reasons. I think part of it was you'd end up checking if crypto is available twice (once with the crypto? inside the useAsyncMemo, and the once with an if verificationStatus == null outside). Another reason was that this way I could make it a const whereas if I put the rest outside, I'd need to create a variable, and then set the value in an if statement. Those are both pretty small reasons, so if the other way is a better match to the coding style of the rest of the app, then I can change it.

const devices = await crypto?.getUserDeviceInfo([member.userId]);
return devices?.get(member.userId) ?? new Map();
},
[context],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
[context],
[context, member],

Comment on lines +48 to +50
const _onBack = (): void => {
setMember(null);
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd be inclined to inline this into the <UserView> invocation

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was copying from another file in the directory, but yeah, it's short enough that it can be inlined.

"unverified": "Verification status: <E2EIcon /> Not signed by owner",
"verified": "Verification status: <E2EIcon /> Verified by cross-signing"
},
"devices": "Devices (%(count)s)",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should probably say something to remind us that this is only devices with keys

Suggested change
"devices": "Devices (%(count)s)",
"devices": "Cryptographic devices (%(count)s)",

maybe? dunno

);
}
},
[],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
[],
[crypto, device],

return _t("devtools|device_verification_status|unverified", {}, { E2EIcon: e2eIcon });
}
},
[],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
[],
[crypto, device],

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Devtool for looking at user devices

2 participants